#define MSAUTOMOUNT_C
#include <sys/types.h>
#include <sys/stat.h>		//mkdir()
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <libmscommon/mscommon.h>
#include <libmscommon/msstring.h>
#include <libmscommon/msthread.h>
#include <libmscommon/msmd.h>
#include <libmslog/mslog.h>
#include "msautomount.h"

#define FLAG  "AUTOMOUNT"
typedef enum MEDIAType{
	MEDIATYPE_NONEXIST 	= -1,
	MEDIATYPE_UNKNOWN	= 0,
	MEDIATYPE_HDD			= 1,
	MEDIATYPE_USB,
	MEDIATYPE_SDCARD,
} MEDIAType;

typedef enum {
	ACTION_PLUGIN = 0,
	ACTION_REMOVE,
	ACTION_NONE,
} Action;


#define PREFIX_MOUNT_HDD  		"/mnt/hdd"
#define PREFIX_MOUNT_USB 		"/mnt/usb"
#define PREFIX_MOUNT_SDCARD 	"/mnt/sdcard"

#define PREFIX_DEV_SDCARD 		"mmcblk"

#define UEVENT_BUFSIZE 		2048
#define MAX_NUM_DEV		6
#define MAX_NUM_PARTITION	9
#define MAX_LEN_DEVNOTE		64	//"sda1"

typedef struct DEVInfo {
	ms_bool flag_mounted;
	ms_byte mount_point[64];
	ms_byte devname[MAX_LEN_DEVNOTE];
	ms_byte partitionname[MAX_LEN_DEVNOTE];
} DEVInfo;
typedef struct MSAMContext {
	DEVInfo 	hddinfo_list[MAX_NUM_DEV];
	DEVInfo 	usbinfo_list[MAX_NUM_DEV];
	DEVInfo 	sdcardinfo_list[MAX_NUM_DEV];
	MSTHREADContext msthread_ctt_mountrecovery;
} MSAMContext;

static MSAMContext msautomount_ctt;
static ms_s08 msam_innerapi_getPartitionInfo(char *devname,ms_byte *pdev_partitioninfo_list)
{
	ms_pamcheckRet(-1, devname, "devname");
	ms_pamcheckRet(-1, pdev_partitioninfo_list, "pdev_partitioninfo_list");
	//Clean partion_info table
	ms_buf0(pdev_partitioninfo_list);
	ms_u08 partition_totalnum = 0;
	ms_u08 partition_devname[MAX_LEN_DEVNOTE] = {0};
	ms_u08 partition_path[128] = {0};
	//Find  partion_info
	ms_u08 parttion_index = 1;
	for (parttion_index = 1; parttion_index <= mscfg_maxnum_partiton; parttion_index++) {
		ms_sprintfs(partition_devname, "%s%d", devname, parttion_index);
		ms_sprintfs(partition_path,"/sys/block/%s/%s", devname, partition_devname);
		if (0 == access(partition_path, F_OK)) {
			ms_byte *pdev_partitioninfo=&pdev_partitioninfo_list[partition_totalnum*MAX_LEN_DEVNOTE];
			ms_strcpy(pdev_partitioninfo, partition_devname);
			partition_totalnum++;
		}
	}
	return partition_totalnum;
}
static MEDIAType msam_innerapi_getMediaType(char* devname)
{
	ms_pamcheckRet(MEDIATYPE_UNKNOWN, devname, "devname");

	ms_u08 dexindex=0;
	DEVInfo 	*phddinfo_list		=msautomount_ctt.hddinfo_list;
	DEVInfo 	*pusbinfo_list		=msautomount_ctt.usbinfo_list;
	DEVInfo 	*psdcardinfo_list	=msautomount_ctt.sdcardinfo_list;
	for (dexindex= 0;dexindex < MAX_NUM_DEV; dexindex++) {
		DEVInfo *pdevinfo=&phddinfo_list[dexindex];
		//ms_debug("------%s,%s",devname, pdevinfo->devname);
		if ( ms_strncmp_seq( pdevinfo->partitionname,devname)
				||ms_strncmp_saeq( pdevinfo->devname,devname)) {
			return MEDIATYPE_HDD;
		}
		pdevinfo=&pusbinfo_list[dexindex];
		//ms_debug("------%s,%s",devname, pdevinfo->devname);
		if ( ms_strncmp_seq( pdevinfo->partitionname,devname)
				||ms_strncmp_saeq( pdevinfo->devname,devname)) {
			return MEDIATYPE_USB;
		}
		pdevinfo=&psdcardinfo_list[dexindex];
		//ms_debug("------%s,%s",devname, pdevinfo->devname);
		if ( ms_strncmp_seq( pdevinfo->partitionname,devname)) {
			return MEDIATYPE_SDCARD;
		}
	}
	return MEDIATYPE_UNKNOWN;
}
static ms_bool msam_innerapi_checkExistDev(char* filename)
{
	return(ms_access(filename,F_OK) < 0) ? ms_false : ms_true;
}
static MEDIAType msam_innerapi_checkMediaType(char* devname)
{
	ms_pamcheckRet(MEDIATYPE_UNKNOWN, devname, "devname");
	MEDIAType media_type=msam_innerapi_getMediaType(devname);
	if(MEDIATYPE_UNKNOWN==media_type){
		char devptype[4] = {0};
		ms_memcpy(devptype, devname, 3);
		char path[256] = {0};
		ms_sprintfs(path,"/sys/block/%s/removable", devptype);
		if (access(path, F_OK)) {
			//ms_debug( "%s isnot exists.",path);
			return MEDIATYPE_NONEXIST;
		}
		ms_s08 chartype = 0;
		if ( 1 !=msmd_api_read2(path, &chartype, 1)) {
			ms_errRet(MEDIATYPE_UNKNOWN,"Read %s failed.",path);
		}
		switch (chartype) {
			case '0':
				media_type = MEDIATYPE_HDD;
				break;
			case '1':
				media_type = MEDIATYPE_USB;
				break;
			default:
				media_type = MEDIATYPE_UNKNOWN;
				break;
		}
	}
	return media_type;
}

static void msam_innerapi_cleanDevInfo(DEVInfo *pdevinfo_list,ms_u08 dexindex)
{
	DEVInfo *pdevinfo=&pdevinfo_list[dexindex];
	pdevinfo->flag_mounted = ms_false;
	ms_buf0(pdevinfo->devname);
	ms_buf0(pdevinfo->partitionname);
}
static void msam_innerapi_showDevInfo(DEVInfo *pdevinfo_list,ms_string namedev_list)
{
	ms_u08 dexindex=0;
	ms_debug("=========================[%s] info=======================",namedev_list);
	ms_debug("index \tdevname \tpartname \tmstatus \tmpoint");
	for (dexindex= 0;dexindex < MAX_NUM_DEV; dexindex++) {
		ms_debug("%03d \t%s \t \t%s \t\t%s \t\t%s", dexindex,pdevinfo_list[dexindex].devname,pdevinfo_list[dexindex].partitionname,
			(ms_true==pdevinfo_list[dexindex].flag_mounted) ? "mount" : "umount",pdevinfo_list[dexindex].mount_point);
	}
	ms_debug("=======================================================");
}
static DEVInfo * msam_innerapi_getDevInfo(char* devname)
{
	MEDIAType media_type = msam_innerapi_checkMediaType(devname);
	DEVInfo 	*phddinfo_list		=msautomount_ctt.hddinfo_list;
	DEVInfo 	*pusbinfo_list		=msautomount_ctt.usbinfo_list;
	DEVInfo 	*psdcardinfo_list	=msautomount_ctt.sdcardinfo_list;
	DEVInfo *pdevinfo_list=ms_null;
	if (MEDIATYPE_HDD == media_type) {
		pdevinfo_list=phddinfo_list;
	}else if (MEDIATYPE_USB == media_type) {
		pdevinfo_list=pusbinfo_list;
	}else if (MEDIATYPE_SDCARD == media_type) {
		pdevinfo_list=psdcardinfo_list;
	}else{
		pdevinfo_list=ms_null;
	}
	return pdevinfo_list;
}
static  ms_bool msam_innerapi_isMounted(char *devname) 
{
	ms_pamcheckRet(ms_false, devname, "devname");
	DEVInfo *pdevinfo_list=msam_innerapi_getDevInfo(devname);
	if(ms_null==pdevinfo_list){
		//ms_errRet(ms_false, "msam_innerapi_getDevInfo  failed");
		return ms_false;
	}
	ms_u08 dexindex=0;
	for (dexindex= 0;dexindex < MAX_NUM_DEV; dexindex++) {
		DEVInfo *pdevinfo=&pdevinfo_list[dexindex];
		if(ms_buflen(pdevinfo->partitionname)>0
			&&ms_true==pdevinfo->flag_mounted){
			ms_debug("target-[devname-partitionname],devname,flag_mounted:%s,[%s-%s],%s",
				devname,pdevinfo->devname,pdevinfo->partitionname, (ms_true==pdevinfo->flag_mounted) ? "mount" : "umount");
			if ( ms_strncmp_seq( pdevinfo->partitionname,devname)
				||ms_strncmp_saeq( pdevinfo->devname,devname)) {
				return ms_true;
			}
		}
	}
	return ms_false;
}

static ms_bool msam_innerapi_mntPartition(DEVInfo **ppdevinfo_list,char *devname,char *partitionname)
{
	//ms_pamcheckRet(ms_false, devname, "devname");
	ms_pamcheckRet(ms_false, partitionname, "partitionname");
	DEVInfo *pdevinfo_list=(*ppdevinfo_list);
	ms_byte pathdev[32]={0};
	ms_sprintfs(pathdev,"/dev/%s",partitionname);
	ms_u08 dexindex = 0;
	for (dexindex = 0; dexindex< MAX_NUM_DEV; dexindex++) {
		DEVInfo *pdevinfo=&pdevinfo_list[dexindex];
		if (ms_true== pdevinfo->flag_mounted){		//has 
			continue;
		}
//set name
		ms_byte umount_cmd[1024]={0};
		ms_byte mount_cmd[1024]={0};
		ms_sprintfs(mount_cmd, "mount | grep  %s", pathdev);
		//ms_debug("mount_cmd:%s",mount_cmd);
		if(ms_true==ms_cmdRet(mount_cmd)){//continue to  mount devname
			ms_sprintfs(umount_cmd, "umount  %s", pathdev);
			//ms_debug("umount_cmd:%s..",umount_cmd);
			ms_cmdRet(umount_cmd);
		}
		ms_sprintfs(mount_cmd, "mount | grep  %s", pdevinfo->mount_point);
		//ms_debug("mount_cmd:%s",mount_cmd);
		if(ms_true==ms_cmdRet(mount_cmd)){//continue to  mount devname
			ms_sprintfs(umount_cmd, "umount  %s", pdevinfo->mount_point);
			//ms_debug("umount_cmd:%s..",umount_cmd);
			ms_cmdRet(umount_cmd);
		}
		ms_sprintfs(mount_cmd, "mount    %s    %s", pathdev, pdevinfo->mount_point);
		ms_debug("mount_cmd:%s",mount_cmd);
		if(ms_false==ms_cmdRet(mount_cmd)){//continue to  mount devname
			ms_sprintfs(mount_cmd, "/bin/ntfs-3g    %s    %s", pathdev, pdevinfo->mount_point);
			ms_debug(" mount_cmd:%s",mount_cmd);
			if(ms_false==ms_cmdRet(mount_cmd)){
				ms_sprintfs(mount_cmd, "mount    -o    iocharset=utf8    %s    %s", pathdev, pdevinfo->mount_point);
				ms_debug(" mount_cmd:%s",mount_cmd);
				if(ms_false==ms_cmdRet(mount_cmd)){
					ms_sprintfs(mount_cmd, "mount    -o    iocharset=utf8    -t    vfat    %s    %s", pathdev, pdevinfo->mount_point);
					ms_debug(" mount_cmd:%s",mount_cmd);
					if(ms_false==ms_cmdRet(mount_cmd)){
						pdevinfo->flag_mounted = ms_false;
						ms_errRet(ms_false, "mount %s(%s) failed.",partitionname,pdevinfo->mount_point);
					}
				}
			}
		}
		if(ms_null!=devname){
			ms_strcpy(pdevinfo->devname, devname);
		}
		ms_strcpy(pdevinfo->partitionname, partitionname);
		pdevinfo->flag_mounted = ms_true;
		ms_info("mount %s(%s) success.",partitionname,pdevinfo->mount_point);
		return ms_true;
	}
	ms_errRet(ms_false,"Too much usb device,out of range:1~%d.",MAX_NUM_DEV);
}
static ms_bool msam_innerapi_mntDev(char *devname)
{
	ms_pamcheckRet(ms_false, devname, "devname");
	DEVInfo *pdevinfo_list=msam_innerapi_getDevInfo(devname);
	if(ms_null==pdevinfo_list){
		return ms_false;
	}
	ms_byte dev_partitioninfo_list[mscfg_maxnum_partiton][MAX_LEN_DEVNOTE];
	ms_u08 partition_totalnum= msam_innerapi_getPartitionInfo(devname,(ms_byte *)dev_partitioninfo_list);
	if (0 > partition_totalnum) {
		ms_errRet(ms_false, "Err devname(%s).",devname);
	}else if ( partition_totalnum == 0 ) {
		if (ms_true != msam_innerapi_mntPartition((DEVInfo **)&pdevinfo_list,devname,devname)) {
			ms_errRet(ms_false, "Mount  devname(%s) failed.",devname);
		}
	} else {
		ms_bool flag_mountdev = ms_false;
		if ( partition_totalnum > MAX_NUM_DEV){
			ms_waring("partition_totalnum(%d) is out of range(0~%d),set to %d", partition_totalnum,MAX_NUM_DEV,MAX_NUM_DEV);
			partition_totalnum = MAX_NUM_DEV;
		}
		ms_u08  partition_index=0;
		for ( partition_index= 0; partition_index< partition_totalnum; partition_index++ ) {
			if (ms_true== msam_innerapi_mntPartition((DEVInfo **)&pdevinfo_list,devname,dev_partitioninfo_list[partition_index])) {
				flag_mountdev = ms_true;
			}
		}
		if (ms_true != flag_mountdev) {
			ms_errRet(ms_false, "Mount  all usb-partition failed.");
		}
	}
	return ms_true;
}
void msam_innerapi_mntExsitDev()
{
	ms_byte 	devname[MAX_LEN_DEVNOTE] = {0};
	ms_byte 	pathdev[MAX_LEN_DEVNOTE+64] = {0};
	ms_u08  	devindex= 0;
	for (devindex = 0;devindex< (MAX_NUM_DEV );devindex++) {
		ms_sprintfs(devname, "sd%c", 'b' + devindex);
		//ms_debug("--------------%s",devname);
		ms_sprintfs(pathdev,"/dev/%s", devname);
		if ( ms_true==msam_innerapi_checkExistDev(pathdev)
			&&ms_false==msam_innerapi_isMounted(devname)) {
			if(ms_true==msam_innerapi_mntDev(devname)){
				ms_debug("mount  %s success",devname);
			}else{
				ms_error("mount  %s failed",devname);
			}
			msam_innerapi_showDevInfo(msautomount_ctt.usbinfo_list, "usbinfo_list");
		}
	}
	DEVInfo 	*psdcardinfo_list	=msautomount_ctt.sdcardinfo_list;
	ms_sprintfs(devname, "%s", "mmcblk0p1");
	ms_sprintfs(pathdev,"/dev/%s",devname);
	if (ms_true==msam_innerapi_checkExistDev(pathdev)
		&&ms_false==msam_innerapi_isMounted(devname)) {
		if(ms_true==msam_innerapi_mntPartition((DEVInfo **)&psdcardinfo_list, devname, devname)){
			ms_debug("mountpartition  %s success",devname);
		}else{
			ms_error("mountpartition  %s failed",devname);
		}
	}
}
void msam_innerapi_mntRecovery(DEVInfo **ppdevinfo_list)
{
	DEVInfo *pdevinfo_list=(*ppdevinfo_list);
	ms_u08 dexindex=0;
	ms_byte mount_cmd[1024]={0};
	ms_byte 	pathdev[MAX_LEN_DEVNOTE+64] = {0};
	ms_bool flag_reset=ms_false;
	for (dexindex= 0;dexindex < MAX_NUM_DEV; dexindex++) {
		if ( ms_buflen(pdevinfo_list[dexindex].partitionname )>0
			&&ms_true==pdevinfo_list[dexindex].flag_mounted){
//no mount recory			
			ms_sprintfs(mount_cmd, "mount | grep  %s", pdevinfo_list[dexindex].mount_point);
			//ms_debug("mount_cmd:%s",mount_cmd);
			if(ms_false==ms_cmdRet(mount_cmd)){//continue to  mount devname
				pdevinfo_list[dexindex].flag_mounted=ms_false;
				ms_byte partitionname[MAX_LEN_DEVNOTE];
				ms_strcpy(partitionname, pdevinfo_list[dexindex].partitionname);
				if(msam_innerapi_mntPartition(ppdevinfo_list,ms_null , partitionname)){
					ms_debug("mountpartition  %s success",partitionname);
				}else{
					ms_error("mountpartition  %s failed",partitionname);
				}
			}
//mount error	
			ms_sprintfs(pathdev,"/dev/%s", pdevinfo_list[dexindex].partitionname);
			if (ms_false==msam_innerapi_checkExistDev(pathdev)){
				ms_waring("dev[%s] isnot exist,but mounted,will be reset mountinfo",pathdev);
				flag_reset=ms_true;
				break;
			}
		}
	}
	if(ms_true==flag_reset){
		for (dexindex= 0;dexindex < MAX_NUM_DEV; dexindex++) {
			msam_innerapi_cleanDevInfo(pdevinfo_list,  dexindex);
		}
	}
}
static ms_bool msam_innerapi_umntPartition(DEVInfo *pdevinfo_list,char *devname)
{
	ms_pamcheckRet(ms_false, devname, "devname");
	ms_u08 dexindex = 0;
	for (dexindex = 0; dexindex< MAX_NUM_DEV; dexindex++) {
		DEVInfo *pdevinfo=&pdevinfo_list[dexindex];
		if ((ms_false== pdevinfo->flag_mounted)
			|| (( ms_true== pdevinfo->flag_mounted) 
					&& (ms_strncmp_snaeq(pdevinfo->devname, devname) )
					&& (ms_strncmp_snaeq(pdevinfo->partitionname, devname) ))
		){
			continue;
		}
		ms_byte umount_cmd[1024]={0};
		ms_byte mount_cmd[1024]={0};
		ms_sprintfs(mount_cmd, "mount | grep  %s", pdevinfo->mount_point);
		//ms_debug("mount_cmd:%s",mount_cmd);
		if(ms_true==ms_cmdRet(mount_cmd)){//continue to  mount devname
			ms_sprintfs(umount_cmd, "umount  %s", pdevinfo->mount_point);
			//ms_debug("umount_cmd:%s..",umount_cmd);
			if(ms_false==ms_cmdRet(umount_cmd)){
				ms_errRet(ms_false, "unmount %s(%s) error.",pdevinfo->partitionname,pdevinfo->mount_point);
			}
		}
		ms_sprintfs(mount_cmd, "mount | grep  /dev/%s", pdevinfo->partitionname);
		//ms_debug("mount_cmd:%s",mount_cmd);
		if(ms_true==ms_cmdRet(mount_cmd)){//continue to  mount devname
			ms_sprintfs(umount_cmd, "umount  /dev/%s", pdevinfo->partitionname);
			//ms_debug("umount_cmd:%s..",umount_cmd);
			if(ms_false==ms_cmdRet(umount_cmd)){
				ms_errRet(ms_false, "unmount %s(%s) error.",pdevinfo->partitionname,pdevinfo->mount_point);
			}
		}
		msam_innerapi_cleanDevInfo(pdevinfo_list,  dexindex);
		return ms_true;
	}
	return ms_false;
}
static ms_bool msam_innerapi_umuntDev(char *devname)
{
	ms_pamcheckRet(ms_false, devname, "devname");
	DEVInfo *pdevinfo_list=msam_innerapi_getDevInfo(devname);
	if(ms_null==pdevinfo_list){
		ms_errRet(ms_false, "msam_innerapi_getDevInfo  failed");
	}
	return msam_innerapi_umntPartition(pdevinfo_list, devname);
}

static char msam_innerapi_actionDone(Action act, char *devname)
{
	ms_bufcheckRetDes(-1, devname, "devname cannot be null");
	switch (act) {
		case ACTION_PLUGIN:
			ms_info("plugin dev:%s",devname);
			if (ms_false== msam_innerapi_isMounted(devname)) {
				if(ms_true==msam_innerapi_mntDev(devname)){
					ms_debug("mount  %s success",devname);
				}else{
					ms_error("mount  %s failed",devname);
				}
				msam_innerapi_showDevInfo(msautomount_ctt.usbinfo_list, "usbinfo_list");
			}else{
				ms_debug("%s has been mounted",devname);
			}
			break;
		case ACTION_REMOVE:
			ms_info("remove dev:%s",devname);
			if (ms_true== msam_innerapi_isMounted(devname)) {
				if(ms_true==msam_innerapi_umuntDev(devname)){
					ms_debug("umount  %s success",devname);
				}else{
					ms_error("umount  %s failed",devname);
				}
				msam_innerapi_showDevInfo(msautomount_ctt.usbinfo_list, "usbinfo_list");
			}else{
				ms_debug("%s isnot mounted",devname);
			}
			break;
		default:
			ms_error("unknown operation.");
			break;
	}
	return 0;
}

/*
 * return 0: no device hotplug operation
 * return 1: has device hotplug operation, see act and devname
 */
static ms_bool msam_innerapi_actionDetect(char * buf, Action *act, char *devname)
{
	ms_pamcheckRet(-1, buf, "buf");
	ms_pamcheckRet(-1, act, "act");
	ms_pamcheckRet(-1, devname, "devname");

	if(ms_true==msstr_api_isCasestr(buf, "add@")){
		*act =ACTION_PLUGIN;
	}else if(ms_true==msstr_api_isCasestr(buf, "remove@")){
		*act =ACTION_REMOVE;
	}else{
		*act =ACTION_NONE;
		return ms_false;
	}
	//ms_info("devname:%s ", buf);
	ms_bool flag_find=ms_false;
	char *p;
	if(ms_true==msstr_api_isCasestr(buf, "block/sd")){
		p = &buf[ strlen(buf) - 1];
		while (*(p-1) != '/'){
			p=p-1;
		}
		ms_strcpy(devname, p);
		//ms_info("devname:%s .", devname);
		flag_find=ms_true;
	}
	if(ms_true==msstr_api_isCasestr(buf, "block/mmcblk0/mmcblk0p1")){
		p = &buf[ strlen(buf) - 1];
		while (*(p-1) != '/'){
			p=p-1;
		}
		ms_strcpy(devname, p);
		//ms_info("devname:%s .(L%d).", devname,__LINE__);
		flag_find=ms_true;
	}
	return flag_find;
}
static void msam_innerapi_monitor(void* arg)
{
	msthread_api_setName("amntMtor");
	MSAMContext *pmsautomount_ctt=(MSAMContext *)arg;
	DEVInfo 	*phddinfo_list		=msautomount_ctt.hddinfo_list;
	DEVInfo 	*pusbinfo_list		=msautomount_ctt.usbinfo_list;
	DEVInfo 	*psdcardinfo_list	=msautomount_ctt.sdcardinfo_list;
	ms_u08 dexindex=0;
	while(1){
		//msam_innerapi_showDevInfo(pusbinfo_list, "pusbinfo_list-bf mountdev_exsit ");
		msam_innerapi_mntExsitDev();
		//msam_innerapi_showDevInfo(pusbinfo_list, "pusbinfo_list-bf remount");
		msam_innerapi_mntRecovery((DEVInfo **)&phddinfo_list);
		msam_innerapi_mntRecovery((DEVInfo **)&pusbinfo_list);
		msam_innerapi_mntRecovery((DEVInfo **)&psdcardinfo_list);
		//msam_innerapi_showDevInfo(pusbinfo_list, "pusbinfo_list-af remount");
		ms_sleep(10);
	}
}
void msam_innerapi_init(DEVInfo 	**pphddinfo_list,ms_string dev_str_prefix)
{
	DEVInfo *phddinfo_list=(*pphddinfo_list);
	ms_byte umount_cmd[1024]={0};
	ms_byte mount_cmd[1024]={0};
	ms_byte cmdbuf[256]={0};
	ms_u08 devindex = 0;
	for (devindex = 0; devindex< MAX_NUM_DEV; devindex++) {
		phddinfo_list[devindex].flag_mounted = ms_false;
		ms_buf0(phddinfo_list[devindex].devname);
		ms_buf0(phddinfo_list[devindex].partitionname);
		ms_sprintfs(phddinfo_list[devindex].mount_point, "%s%c", dev_str_prefix, '0' + devindex + 1);
//create 	mount_point	
		ms_cmd(cmdbuf, "mkdir    -p   %s", phddinfo_list[devindex].mount_point);
//if mount_point is used,umount it	
		ms_sprintfs(mount_cmd, "mount | grep  %s", phddinfo_list[devindex].mount_point);
		if(ms_true==ms_cmdRet(mount_cmd)){//continue to  mount devname
			ms_sprintfs(umount_cmd, "umount  %s", phddinfo_list[devindex].mount_point);
			if(ms_true==ms_cmdRet(umount_cmd)){
				ms_debug("umount  %s  success",phddinfo_list[devindex].mount_point);
			}else{
				ms_debug("umount  %s  error",phddinfo_list[devindex].mount_point);
			}
		}
	}
}
void msautomnt_api_init()
{
	ms_stru0(&msautomount_ctt, MSAMContext);
	DEVInfo 	*phddinfo_list		=msautomount_ctt.hddinfo_list;
	DEVInfo 	*pusbinfo_list		=msautomount_ctt.usbinfo_list;
	DEVInfo 	*psdcardinfo_list	=msautomount_ctt.sdcardinfo_list;
//init  hdd 	
	msam_innerapi_init(&phddinfo_list, PREFIX_MOUNT_HDD);
//init  usb 
	msam_innerapi_init(&pusbinfo_list, PREFIX_MOUNT_USB);
//init  sdcard
	msam_innerapi_init(&psdcardinfo_list, PREFIX_MOUNT_SDCARD);
	msthread_api_create(&msautomount_ctt.msthread_ctt_mountrecovery,"msmonut_monitor",msam_innerapi_monitor,&msautomount_ctt);
}
void msautomnt_api_deinit()
{
	msthread_api_destroy(&msautomount_ctt.msthread_ctt_mountrecovery);
}
void msautomnt_api_detectHotplug()
{
	char devname[MAX_LEN_DEVNOTE] = {0};
	
	char buf[UEVENT_BUFSIZE] = { 0 };
	int listen_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
	
	/* receive broadcast message*/
	int buffersize = 1024;
	setsockopt(listen_fd, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
	
	struct sockaddr_nl client; 
	memset(&client, 0, sizeof(client));
	client.nl_family = AF_NETLINK;
	client.nl_pid = getpid();
	client.nl_groups = 1;
	bind(listen_fd, (struct sockaddr*)&client, sizeof(client));

	fd_set fds;
	while (1) {
		FD_ZERO(&fds);
		FD_SET(listen_fd, &fds);
		
		struct timeval tv;
		memset(&tv,0x00,sizeof(struct timeval));
		tv.tv_sec = 0;
		tv.tv_usec = 100 * 1000;
		
		int ret = select(listen_fd + 1, &fds, ms_null, ms_null, &tv);
		if(ret < 0){
			continue;
		}else if(!(ret > 0 && FD_ISSET(listen_fd, &fds))){
			continue;
		}else{
			int rcvlen = recv(listen_fd, &buf, sizeof(buf), 0);
			if (rcvlen > 0) {
				Action act = ACTION_NONE;
				ms_buf0(devname);
				if (ms_true==msam_innerapi_actionDetect(buf, &act, devname)){
        					msam_innerapi_actionDone(act, devname);
				}
			} 
			ms_buf0(buf);
		}
	}
	close(listen_fd);
}
#undef MSAUTOMOUNT_C